package com.lovezy.platform.message.email.service.impl;

import com.lovezy.platform.core.base.enums.TrueOrFalseEnum;
import com.lovezy.platform.core.base.query.Pager;
import com.lovezy.platform.core.base.service.MapperService;
import com.lovezy.platform.core.email.EmailSender;
import com.lovezy.platform.core.exception.DefaultErrorCode;
import com.lovezy.platform.core.exception.ServiceException;
import com.lovezy.platform.message.email.enums.EmailIllegalEnum;
import com.lovezy.platform.message.email.enums.EmailTypeEnum;
import com.lovezy.platform.message.email.mapper.EmailMapper;
import com.lovezy.platform.message.email.model.Email;
import com.lovezy.platform.message.email.model.EmailExample;
import com.lovezy.platform.message.email.service.EmailService;
import com.lovezy.platform.message.email.service.EmailServiceTarget;
import com.lovezy.platform.message.email.service.VerifyEmailResult;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Optional;
import java.util.function.Function;

/**
 * 邮箱服务实现
 * Created by jin on 2017/11/9.
 */
@Service
public class EmailServiceImpl extends MapperService<Email,Integer,EmailMapper> implements EmailService{

    @Autowired
    private EmailSender emailSender;

    @Override
    public Email sendEmail(EmailServiceTarget target) {
        checkTarget(target);
        Date now = new Date();
        Email email = new Email();
        email.setMemberId(target.getMemberId());
        email.setType(target.getEmailType().value());
        email.setUsed(TrueOrFalseEnum.FALSE.value());
        email.setAuthKey(target.getAuthKey());
        email.setEmail(target.getAddress());
        email.setGmtCreate(now);
        email.setGmtModify(now);
        mapper.insertSelective(email);
        emailSender.send(target);
        return email;
    }

    @Override
    public void verifyEmail(@NotNull String authKey, @NotNull EmailTypeEnum type, Function<VerifyEmailResult,Boolean> handler) {
        Optional<Email> emailOptional = findEmail(authKey);
        VerifyEmailResult result = new VerifyEmailResult();
        if (!emailOptional.isPresent()) {
            result.setIllegal(EmailIllegalEnum.NOT_FOUND);
            handler.apply(result);
            return;
        }
        Email email = emailOptional.get();
        result.setEmail(email);
        if (email.getUsed() == TrueOrFalseEnum.TRUE.value()) {
            result.setIllegal(EmailIllegalEnum.ALREADY_USED);
            handler.apply(result);
            return;
        }
        if (email.getType() != type.value()) {
            result.setIllegal(EmailIllegalEnum.TYPE_ERROR);
            handler.apply(result);
            return ;
        }
        result.setSuccess(true);
        Boolean canUpdate = handler.apply(result);
        if (canUpdate) {
            Email updateEmail = new Email();
            updateEmail.setEmailNo(email.getEmailNo());
            updateEmail.setGmtModify(new Date());
            updateEmail.setUsed(TrueOrFalseEnum.TRUE.value());
            mapper.updateByPrimaryKeySelective(updateEmail);
        }
    }

    private Optional<Email> findEmail(@NotNull String authKey) {
        EmailExample example = new EmailExample();
        example.createCriteria()
                .andAuthKeyEqualTo(authKey)
                .andUsedEqualTo(TrueOrFalseEnum.FALSE.value());
        return Pager.doSingleton(() -> mapper.selectByExample(example));
    }

    private void checkTarget(EmailServiceTarget target) {
        if (target.getEmailType() == null) {
            throw new ServiceException(DefaultErrorCode.SERVICE_ERROR, "邮件类别为空");
        }
    }

}
